package com.xinchuang.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.MD5;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xinchuang.comment.R;
import com.xinchuang.common.KeyWordSystem;
import com.xinchuang.common.Result;
import com.xinchuang.common.ResultUtil;
import com.xinchuang.entity.User;
import com.xinchuang.entity.UserRole;
import com.xinchuang.entity.common.FileTable;
import com.xinchuang.entity.repacigi.RepacigiBaseTable;
import com.xinchuang.entity.targetSystem.system.TargetType;
import com.xinchuang.mapper.UserMapper;
import com.xinchuang.mapper.UserRoleMapper;
import com.xinchuang.mapper.targetSystem.TargetTypeMapper;
import com.xinchuang.service.PublicService;
import com.xinchuang.service.common.FileTableService;
import com.xinchuang.service.common.ImgTargetTableService;
import com.xinchuang.service.image.GDALService;
import com.xinchuang.service.repacigi.RepacigiBaseTableService;
import com.xinchuang.util.RedisUtil;
import com.xinchuang.utils.CommonUtil;
import com.xinchuang.utils.MercatorWmtsUtils;
import com.xinchuang.utils.MyUtil;
import com.xinchuang.utils.ObjectUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Service
@RequiredArgsConstructor
public class PublicServiceImpl implements PublicService {

    private static DateTimeFormatter sdf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm-ss");

    private final UserMapper userMapper;

    private final UserRoleMapper userRoleMapper;

    private final FileTableService fileTableService;

    private final ImgTargetTableService imgTargetTableService;

    private final KeyWordSystem keyWordSystem;

    private final RedisUtil redisUtil;

    private final TargetTypeMapper targetTypeMapper;

    private final RepacigiBaseTableService repacigiBaseTableService;

    private final GDALService gdalService;

    @Override
    public String uploadFile(MultipartFile fileData) {
        if (null != fileData) {
            String oriName = fileData.getOriginalFilename();
            String id = String.valueOf(System.currentTimeMillis());
            String path = "/file/" + id + "_" + oriName;
            FileUtil.mkdir(keyWordSystem.getFILE_URL() + "/file");
            FileTable fileTable = new FileTable();
            fileTable.setName(oriName.substring(0, oriName.lastIndexOf(".")));
            fileTable.setCreateTime(LocalDateTime.now());
            fileTable.setFileSize(String.valueOf(fileData.getSize()));
            fileTable.setFileUrl(path);
            fileTable.setType(String.valueOf(oriName.split("\\.")[1]));
            fileTable.setUpdateTime(LocalDateTime.now());
            fileTable.setFileId(id);
            try {
                fileData.transferTo(new File(keyWordSystem.getFILE_URL() + path));
                fileTableService.save(fileTable);
            } catch (IOException e) {
                e.printStackTrace();
            }
            JSONObject fileJson = new JSONObject();
            fileJson.put("fileName", fileTable.getName());
            fileJson.put("fileSize", fileTable.getFileSize());
            fileJson.put("fileUrl", fileTable.getFileUrl());
            fileJson.put("fileType", fileTable.getType());
            fileJson.put("uploadTime", sdf.format(fileTable.getUpdateTime()));
            return JSON.toJSONString(R.data(fileJson));
        } else {
            return JSON.toJSONString(R.success("无数据"));
        }
    }

    @Override
    public Result uploadTif(MultipartFile imgData) {
        if (null != imgData) {
            String oriName = imgData.getOriginalFilename();
            String id = String.valueOf(System.currentTimeMillis());
            String path = "/image/" + id + "/" + oriName;
            FileUtil.mkdir(keyWordSystem.getFILE_URL() + "/image/" + id);
            FileTable fileTable = new FileTable();
            fileTable.setName(oriName.substring(0, oriName.lastIndexOf(".")));
            fileTable.setFileSize(String.valueOf(imgData.getSize()));
            fileTable.setFileUrl(path);
            fileTable.setType(String.valueOf(oriName.split("\\.")[1]));
            fileTable.setCreateTime(LocalDateTime.now());
            fileTable.setUpdateTime(LocalDateTime.now());
            fileTable.setFileId(id);
            try {
                imgData.transferTo(new File(keyWordSystem.getFILE_URL() + path));
                switch (oriName.substring(oriName.toLowerCase().lastIndexOf("."), oriName.length())) {
                    case ".tif":
                    case ".tiff":
                        CommonUtil.generateThumbnail(keyWordSystem.getFILE_URL() + path, keyWordSystem.getFILE_URL() + "/image/" + id + "/" + "thumb.jpg", 200, 200);
                        CommonUtil.getImage(keyWordSystem.getFILE_URL() + path, keyWordSystem.getFILE_URL() + "/image/" + id + "/" + fileTable.getName() +  ".jpg");
                        break;
                    default:
                        return ResultUtil.error(500, "当前文件类型不支持，请选择（tif/tiff影像）");
                }
                fileTable.setImgUrl("/image/" + id + "/" + fileTable.getName() +  ".jpg");
                fileTable.setThumb("/image/" + id + "/" + "thumb.jpg");
                fileTableService.save(fileTable);
            } catch (IOException e) {
                e.printStackTrace();
                return ResultUtil.error(500, "系统异常，请稍后重试");
            }
            JSONObject fileJson = new JSONObject();
            fileJson.put("fileId", fileTable.getFileId());
            fileJson.put("imgName", fileTable.getName());
            fileJson.put("imgSize", fileTable.getFileSize());
            fileJson.put("fileUrl", fileTable.getFileUrl());
            fileJson.put("imgType", fileTable.getType());
            fileJson.put("imgTime", sdf.format(fileTable.getUpdateTime()));
            fileJson.put("imgUrl", fileTable.getImgUrl());
            fileJson.put("icon", fileTable.getThumb());
            return ResultUtil.success(fileJson);
        } else {
            return ResultUtil.error(500, "无数据");
        }
    }

    @Override
    public Result uploadImg(MultipartFile imgData) {
        if (ObjectUtil.isNotEmpty(imgData)) {
            String oriName = imgData.getOriginalFilename();
            String id = String.valueOf(System.currentTimeMillis());
            String path = "/image/" + id + "/" + oriName;
            FileUtil.mkdir(keyWordSystem.getFILE_URL() + "/image/" + id);
            FileTable fileTable = new FileTable();
            fileTable.setName(oriName.substring(0, oriName.lastIndexOf(".")));
            fileTable.setFileSize(String.valueOf(imgData.getSize()));
            fileTable.setFileUrl(path);
            fileTable.setType(String.valueOf(oriName.split("\\.")[1]));
            fileTable.setCreateTime(LocalDateTime.now());
            fileTable.setUpdateTime(LocalDateTime.now());
            fileTable.setFileId(id);
            try {
                String suff = oriName.substring(oriName.toLowerCase().lastIndexOf("."));
                switch (suff) {
                    case ".png":
                    case ".jpg":
                    case ".jpeg":
                    case ".bmp":
                    case ".gif":
                    case ".webp":
                        imgData.transferTo(new File(keyWordSystem.getFILE_URL() + path));
                        break;
                    default:
                        return ResultUtil.error(500, "当前文件类型不支持");
                }
                fileTable.setImgUrl("/image/" + id + "/" + fileTable.getName() + suff);
            } catch (IOException e) {
                e.printStackTrace();
                return ResultUtil.error(500, "系统异常，请稍后重试");
            }
            JSONObject fileJson = new JSONObject();
            fileJson.put("imgName", fileTable.getName());
            fileJson.put("imgSize", fileTable.getFileSize());
            fileJson.put("fileUrl", fileTable.getFileUrl());
            fileJson.put("imgType", fileTable.getType());
            fileJson.put("imgTime", sdf.format(fileTable.getUpdateTime()));
            fileJson.put("imgUrl", fileTable.getImgUrl());
            fileJson.put("icon", "");
            return ResultUtil.success(fileJson);
        } else {
            return ResultUtil.error(500, "无数据");
        }
    }

    @Override
    public String countryList(JSONObject jsonObject) {
        //jsonobject解析获取类型
        String type = jsonObject.getString("type");
        //
        String typeId = jsonObject.getString("typeId");
        List<Map<String, Object>> resultList = new ArrayList<>();
        if ("0".equals(type)) {
            List<Object> countrys = redisUtil.lGet(keyWordSystem.getVERSION() + "country", 0, -1);
            for (Object o : countrys) {
                Map<String, Object> map = new HashMap<>();
                map.put("value", o);
                map.put("label", o);
                resultList.add(map);
            }
        } else {
            List<RepacigiBaseTable> baseTables = repacigiBaseTableService
                    .lambdaQuery()
                    .eq(RepacigiBaseTable::getType, 0)
                    .orderByAsc(RepacigiBaseTable::getCreateTime)
                    .list();
            baseTables.forEach(data -> {
                Map<String, Object> map = new HashMap<>();
                map.put("label", data.getTypeName());
                map.put("value", data.getTypeId());
                resultList.add(map);
            });
        }
        return JSON.toJSONString(R.data(resultList));
    }

    @Override
    public Result login(JSONObject jsonObject) {
        //jsonobject解析获取用户名
        String userName = jsonObject.getString("userName");
        //jsonobject解析获取密码
        String password = jsonObject.getString("password");
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", userName);
        queryWrapper.eq("password", password);
        User user = userMapper.selectOne(queryWrapper);
        if (null != user) {
            JSONObject userInfoJson = new JSONObject();
            QueryWrapper<UserRole> userRoleQueryWrapper = new QueryWrapper<>();
            userRoleQueryWrapper.eq("user_id", user.getId());
            UserRole userRole = userRoleMapper.selectOne(userRoleQueryWrapper);
            String digestHex = MD5.create().digestHex(user.getId() + DateUtil.format(new Date(), "yyyyMMddHHmmssS"));
            userInfoJson.put("id", digestHex);
            userInfoJson.put("xName", user.getName());
            userInfoJson.put("role", userRole.getRoleId());
            userInfoJson.put("token", digestHex);
            redisUtil.set("USER_KUNMING_ENCRYPT_" + user.getId(), digestHex, 60 * 60 * 24);
            redisUtil.set("USER_KUNMING_USERID_" + digestHex, user.getId(), 60 * 60 * 24);
            return ResultUtil.success(userInfoJson);
        } else {
            return ResultUtil.error(401, "用户不存在");
        }
    }

    @Override
    public Result uploadTypeTif(MultipartFile imgData, String tarId, int type) {
        if (null != imgData) {
            String oriName = imgData.getOriginalFilename();
            String suff = oriName.substring(oriName.toLowerCase().lastIndexOf("."), oriName.length());
            String id = String.valueOf(System.currentTimeMillis());
            String path = "/image/" + id + "/" + UUID.randomUUID().toString() + suff;
            FileUtil.mkdir(keyWordSystem.getFILE_URL() + "/image/" + id);
            try {
                imgData.transferTo(new File(keyWordSystem.getFILE_URL() + path));
                String remark = "";
                String redisKey = "REDIS_IMAGES_";
                if (0 == type) {
                    redisKey += "BASE";
                    remark = "基准影像_" + DateUtil.format(new Date(), "yyyyMMddHHmmss");
                } else if (1 == type) {
                    redisKey += "NEW";
                    remark = "最新影像_" + DateUtil.format(new Date(), "yyyyMMddHHmmss");
                } else {
                    redisKey += "RESULT";
                    remark = "识别影像_" + DateUtil.format(new Date(), "yyyyMMddHHmmss");
                }
                switch (suff) {
                    case ".tif":
                    case ".tiff":
                        gdalService.tifCut(tarId, path, type, remark);
                        redisUtil.hset(tarId + redisKey, "影像处理中请稍后", "1", 60 * 60);
                        break;
                    default:
                        return ResultUtil.error(500, "当前文件类型不支持，请选择（tif/tiff影像）");
                }

            } catch (IOException e) {
                return ResultUtil.error(500, "系统异常，请稍后重试");
            }
            return ResultUtil.success("影像正在上传，请耐心等待");
        } else {
            return ResultUtil.error(500, "上传影像不能为空");
        }
    }

}
